"""
http://forum.simwe.com/thread-859032-1-1.html
 a[[150000]]={69073, -89238, -305675}
 Times@@a[[150000]]=1884161251122450

http://projecteuler.net/index.php?section=forum&id=221&page=1
"""

;;; duplicated 
(defun range (start end &optional (step 1))
  (loop for i from start to end by step collect i)) 

;;; copy from p12.lisp
;;; first half divisors
(defun divisors-of (num)
  (remove-if-not
	(lambda (x) (= (mod num x) 0))
	(range 1 (floor (sqrt num)))))

;;; fold multiple dimension list to single demension list
;;; any build-in function?
;;; stack overflow when alist contains a large amount of items
(defun fold-list-recur (alist)
  (if (zerop (length alist)) alist
	  (append (car alist) (fold-list-recur (cdr alist)))))

(defun fold-list-iteractive (alist)
	(do ((result '() (append result (car tmplist)))
		 (tmplist alist (cdr tmplist)))
	    ((null tmplist) result)))

;(format t "~a~%" (time (fold-list-recur '((2 3) (4 5) (8 9)))))
;(format t "~a~%" (time (fold-list-iteractive '((2 3) (4 5) (8 9)))))

(defparameter range-limit 100)

(defun p221 ()
  (mapcar
	(lambda (x)
	        (mapcar 
			  (lambda (y) (* x (+ x y) (+ x (/ (1+ (expt x 2)) y))))
			  (divisors-of (1+ (expt x 2)))))
	(range 1 range-limit)))

(defun p221-1 ()
  (loop for x from 1 to range-limit
		collect (dolist (y (divisors-of (1+ (expt x 2))))
			            (* x (+ x y) (+ x (/ (1+ (expt x 2)) y))))))

(format t "~a~%" (time (length (p221))))
(format t "~a~%" (time (length (p221-1))))
